/**
 * @file communicate.h
 * @brief 通信模块头文件
 *        定义通信协议帧头、数据结构、枚举类型及通信相关函数声明
 * @author WeiFan Qiu (qiuweifan0523@faxmail.com)
 * @version 1.0
 * @date 2025-08-08
 * 
 * @copyright Copyright (c) 2025  邱伟凡
 * 
 * @par 修改日志:
 * - 2025-08-08: 初始版本创建
 * 
 * @bug 待解决问题:
 * - 通信协议兼容性扩展问题
 * - 数据校验机制完善
 */
#ifndef COMMUNICATE_H
#define COMMUNICATE_H
//#pragma pack(1)//1字节对齐
#include <stdint.h>
#include "QWF_Can.h"
#include "Ctrl.h"
#include "Judge.h"
#include "QWF_Custom_Ctrl.h"
#pragma pack(push, 1)      // 设置结构体1字节对齐（避免成员间填充)
/**
 * @brief 裁判系统模块常用数据处理
 */
#define initial_speed_tar		22.7		///< 初始弹速目标值
#define initial_speed_tar_range	0.1f		///< 初始弹速允许误差范围
#define my_fire_speed_diff 		(communicate->chassis.judge.data.str.initial_speed_diff/10.0f)	///< 实际弹速差值（裁判系统数据转换）
#define my_speed_add			100			///< 弹速增量
#define fire_max				6700		///< 最大射速限制
/**
 * @brief 云台控制模式枚举
 */
typedef enum{
	gimbal_stop=0,		///< 云台停止模式（无控制输出）
	gimbal_yes,			///< 不控制云台（改控制底盘角速度）
	gimbal_normal,		///< 云台正常控制旋转模式
	gimbal_vision,		///< 视觉跟随模式（根据视觉数据调整云台）
	gimbal_vision_test,	///< 视觉跟随测试模式（调试用）
	gimbal_mode_num		///< 云台模式数量（用于数组索引）
}gimbal_mode_e;

/**
 * @brief 发弹机构控制模式枚举
 */
typedef enum{
	fire_stop=0,		///< 停止发射模式（无弹丸输出）
	fire_yes,			///< 正常发射模式（连续供弹）
	fire_knob_stop,		///< 仅拨盘停止模式（电机运行但拨盘不动）
	fire_once,			///< 单发模式（电机转n圈拨一次弹）
	fire_continuous,	///< 连发模式（持续拨弹）
	shoot_mode_num		///< 发弹模式数量（用于数组索引）
}shoot_mode_e;

/**
 * @brief 视觉目标类型枚举（与队伍颜色组合使用）
 */
typedef enum{
	vision_car=0,			///< 车辆目标（基础类型）
	vision_small_flag=2,	///< 小能量机关目标
	vision_big_flag=4,		///< 大能量机关目标
}vision_mode_type;

/**
 * @defgroup 视觉模式组合宏
 * @brief 根据己方队伍颜色（my_team）生成具体视觉模式
 */
#define vision_mode_car			my_team+vision_car			///< 车辆视觉模式（红/蓝）
#define vision_mode_small_flag	my_team+vision_small_flag	///< 小能量机关视觉模式（红/蓝）
#define vision_mode_big_flag	my_team+vision_big_flag		///< 大能量机关视觉模式（红/蓝）
//0:自瞄红 1:自瞄蓝 2:小符红 3:小符蓝4:大符红 5:大符蓝
/**
 * @brief 通信数据帧头枚举（最多支持31种数据类型）
 */
typedef enum{
	/*云台双板数据*/
	Head_Need_Data				=0,		///< 云台需要的数据请求，用于底盘长时间缺少某帧时索求发送
	Ctrl_Befor_Data				=1,		///< 遥控器前半部分缓冲区数据
	Ctrl_Later_Data				=2,		///< 遥控器后半部分缓冲区数据
	Head_Mode_Data				=3,		///< 头部模式数据
	Vision_Data					=4,		///< 视觉相关数据
	/*底盘双板数据*/ 
	Chassis_Need_Data			=5,		///< 底盘需要的数据请求,用于云台长时间缺少某帧时所求发送
	Judge_Data					=6,		///< 裁判系统数据
	/*总数量*/                    
	communicate_num				///< 通信数据类型总数（用于数组索引）
}communicate_head_e;

/**
 * @brief CAN双板通信接收数据结构体模板（8字节帧格式）
 */
typedef struct{
	uint8_t 	head_1:5;	///< 帧头1（5位，对应communicate_head_e枚举）
	uint8_t 	head_2:3;	///< 帧头2，用于特殊校验等
	uint8_t	 	data[7];	///< 数据（7字节）
}communicate_rx_t;

/**
 * @struct communicate_t
 * @brief 通信数据主结构体（包含所有通信相关子数据）
 */
typedef struct{
	communicate_head_e id;
	struct{//云台部分双板
		struct{//遥控器缓冲区 ctrl
			struct{//前半部分 befor
				communicate_head_e head:5;	///< 数据帧头（5位）
				ctrl_type_e type:2;			///< 控制器类型（2位）
				ctrl_mode_e mode:1;			///< 控制模式（1位）
				union{
					uint8_t buffer[7];		///< 原始数据缓冲区（7字节）
				}data;
				struct{
					float	tick;			///< 在线计时（用于超时检测）
					_Bool 	yes;			///<是否在线		
				}online;				
				_Bool	use;				///< 数据有效标志位
			}befor;

			struct{//后半部分 later
				communicate_head_e head_1:5;///< 数据帧头（5位）
				uint8_t 		   head_2:3;///< 控制器类型（3位）
				union{
					uint8_t buffer[7];		///< 原始数据缓冲区（7字节）
				}data;
				struct{
					float	tick;			///< 在线计时（用于超时检测）
					_Bool 	yes;			///<是否在线		
				}online;
				_Bool	use;				///< 数据有效标志位
			}later;
		}ctrl;
		
		struct{//云台模式 mode
			communicate_head_e head_1:5;///< 数据帧头（5位）
			uint8_t 		   head_2:3;///< 控制器类型（3位）
			union{
				uint8_t buffer[7];		///< 原始数据缓冲区（7字节）
				struct{
					uint8_t gimbal;		///< 云台模式（对应gimbal_mode_e）
					uint8_t shoot;		///< 发弹模式（对应shoot_mode_e）
					uint8_t vision;		///< 视觉模式（对应vision_mode_type）
					_Bool	use_fire_loop:1;///< 射速闭环启用标志
					_Bool	use_vision_fire:1;///< 视觉触发发射标志
				}str;					///< 结构化模式数据
			}data;
			struct{
				float	tick;			///< 在线计时（用于超时检测）
				_Bool 	yes;			///<是否在线		
			}online;
			_Bool	use;				///< 数据有效标志位
		}mode;

		struct{//视觉部分 vision
			communicate_head_e 	head_1:5;///< 数据帧头（5位）
			uint8_t 			head_2:3;///< 控制器类型（3位）
			union{
				uint8_t buffer[7];		///< 原始数据缓冲区（7字节）
				struct{
					uint8_t fire:1;		///< 视觉发弹标志（1位）
					_Bool   head_ok:1;	///< 视觉模块在线标志
					uint8_t diatance:4;	///< 视觉目标距离（4位，0-15级）
				}str;					///< 结构化视觉数据
			}data;
			struct{
				float	tick;			///< 在线计时（用于超时检测）
				_Bool 	yes;			///<是否在线		
			}online;
			_Bool	use;				///< 数据有效标志位
		}vision;
		
		struct{//数据申请 need
			communicate_head_e 	head_1:5;///< 数据帧头（5位）
			uint8_t 		   	head_2:3;///< 控制器类型（3位）
			union{
				uint8_t buffer[7];		///< 原始数据缓冲区（7字节）
				communicate_head_e e;	///< 请求的数据类型（对应communicate_head_e）
			}data;
			struct{
				float	tick;			///< 在线计时（用于超时检测）
				_Bool 	yes;			///<是否在线		
			}online;
			_Bool	use;				///< 数据有效标志位
		}need;
	}head;

	struct{
		struct{//裁判系统 judge
			communicate_head_e head_1:5;///< 数据帧头（5位）
			uint8_t 		   head_2:3;///< 控制器类型（3位）
			union{
				uint8_t buffer[7];		///< 原始数据缓冲区（7字节）
				struct{
					my_team_e my_team:1;///< 己方队伍（0:红队，1:蓝队）
					int8_t   initial_speed_diff:8;///< 初始弹速差值（裁判系统给定）
					uint8_t  heat_max:7;	///< 最大热量限制（7位，0-127）
					uint8_t  heat_now:7;	///< 当前热量值（7位，0-127）
					uint8_t  heat_cooling:4;///< 热量冷却速率（4位，0-15）
					uint8_t  level:4;		///< 机器人等级（4位，0-15）
				}str;					///< 结构化裁判数据
			}data;
			struct{
				float	tick;			///< 在线计时（用于超时检测）
				_Bool 	yes;			///<是否在线		
			}online;
			_Bool	use;				///< 数据有效标志位
		}judge;

		struct{//数据申请 need
			communicate_head_e head_1:5;///< 数据帧头（5位）
			uint8_t 		   head_2:3;///< 控制器类型（3位）
			union{
				uint8_t buffer[7];		///< 原始数据缓冲区（7字节）
				communicate_head_e e;	///< 请求的数据类型（对应communicate_head_e）
			}data;
			struct{
				float	tick;			///< 在线计时（用于超时检测）
				_Bool 	yes;			///<是否在线		
			}online;
			_Bool	use;				///< 数据有效标志位
		}need;
	}chassis;
}communicate_t;

extern communicate_t* communicate;	///< 通信数据主结构体实例指针
/**
 * @brief 通信数据处理函数
 */
void comunicate_cal(communicate_rx_t* data);
#pragma pack(pop)  // 恢复默认结构体对齐方式
#endif
